﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO.Compression;
using System.Text;
using System.Linq;
using System.Web.Security;
using System.Web;

using Enterprise.Infrastructure;
using Enterprise.Model.Role;
using Enterprise.Model.Module;
using Enterprise.Service.User;
namespace Enterprise.Service
{
   public class PermissionService:IHttpModule
    {
        /// <summary>
        /// 读取配置状态
        /// </summary>
        public static bool InitState = true;
        internal delegate void DelegateCheckUpdate();

        /// <summary>
        /// 应用启动时间
        /// </summary>
        public static DateTime AppStartTime;

        void IHttpModule.Init(HttpApplication app)
        {
            app.BeginRequest += new EventHandler(app_HttpGZip);
            app.Error += new EventHandler(app_Error);
            app.AuthenticateRequest += new EventHandler(app_AuthMethod);
            app.AcquireRequestState += new EventHandler(app_Auth);
            AppStartTime = DateTime.Now;
        }

        /// <summary>
        /// HttpGZip压缩
        /// </summary>
        /// <param name="ob"></param>
        /// <param name="ex"></param>
        private void app_HttpGZip(object ob, EventArgs ex)
        {
            //UserOnlineService.ClearTimeOut();
            if ((InitState) && true)
            {
                HttpApplication ap = ob as HttpApplication;
                if (Utility.GetScriptNameExt.ToLower() == "aspx" && ap.Request.Headers["Accept-encoding"] != null && ap.Request.Headers["Accept-encoding"].Contains("gzip"))
                {
                    ap.Response.Filter = new GZipStream(ap.Response.Filter, CompressionMode.Compress);
                    ap.Response.AppendHeader("Content-encoding", "gzip");
                    ap.Response.AppendHeader("Vary", "Content-encoding");
                }
            }
        }

        /// <summary>
        /// 系统认证方法
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="ex"></param>
        private void app_AuthMethod(object sender, EventArgs ex)
        {
            //判断文件名为aspx
            if (Utility.GetScriptNameExt.ToLower() == "aspx")
            {
                //检测方法权限设置
                HttpApplication App = (HttpApplication)sender;
                string cookieName = FormsAuthentication.FormsCookieName;
                HttpCookie authCookie = App.Context.Request.Cookies[cookieName];

                if (null == authCookie)
                {
                    // 沒有驗證 Cookie。
                    return;
                }
                FormsAuthenticationTicket authTicket = null;
                try
                {
                    authTicket = FormsAuthentication.Decrypt(authCookie.Value);
                }
                catch (Exception e)
                {
                    // 記錄例外狀況詳細資料 (為簡單起見已省略)
                    LogHelper.WriteLog(ex.ToString());
                    return;
                }

                if (null == authTicket)
                {
                    // Cookie 無法解密。
                    return;
                }

                // 建立 Identity 物件
                FormsIdentity id = new FormsIdentity(authTicket);
                App.Context.User = new PermissionPrincipal(id);
            }

        }


        /// <summary>
        /// 处理认证成功事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void app_Auth(object sender, EventArgs e)
        {
            int UserId = Utility.Get_UserId;
            //判断
            if (Utility.GetScriptNameExt.ToLower() == "aspx" && UserId != 0)
            {
                //检测权限
                if (!Check_Permission)
                {
                    System.Web.HttpContext.Current.Response.Redirect("/Error.aspx");
                    System.Web.HttpContext.Current.Response.End();
                }
            }
        }

        /// <summary>
        /// 处理出错日志
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void app_Error(object sender, EventArgs e)
        {

            HttpApplication ap = sender as HttpApplication;
            Exception ex = ap.Server.GetLastError();
            if (ex is HttpException)
            {
                HttpException hx = (HttpException)ex;
                if (hx.GetHttpCode() == 404)
                {
                    string page = ap.Request.PhysicalPath;
                    LogHelper.WriteLog(string.Format("文件不存在:{0}", ap.Request.Url.AbsoluteUri));
                    return;
                }
            }
            if (ex.InnerException != null) ex = ex.InnerException;
            //日志接入口
            LogHelper.WriteLog(ex.Source + " thrown " + ex.GetType().ToString() + "<br />" + ex.Message.Replace("\r", "").Replace("\n", "<br />") + "<br />" + ex.StackTrace.Replace("\r", "").Replace("\n", "<br />"));
            //if (!General.DispError)
            //{
            //    if (General.GetScriptName.ToLower().IndexOf("messages.aspx") < 0)
            //    {
            //        ap.Response.Redirect("~/Messages.aspx?CMD=AppError");
            //    }
            //}
        }


        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool Check_Permission
        {
            get
            {
                PermissionEntity Pis = Get_Permission;
                if (Pis == null)
                    return true;
                if (HttpContext.Current.User.Identity.IsAuthenticated)
                {
                    int UserId = Utility.Get_UserId;
                    UserService uService = new UserService();
                    if (uService.UserDisp(UserId).UADMIN == "1") //如为超级用户
                        return true;
                    //检测页面文件名访问权限
                    PermissionItemEntity PsItem = Get_PermissionItem(Pis.ItemList);
                    if (PsItem == null)
                        return false;
                    if (string.IsNullOrEmpty(Utility.GetScriptNameQueryString))
                        return UserPermissionService.CheckPageCode(UserId, Pis.ApplicationId, Pis.PageCode, PsItem.Item_Value);
                    else
                    {
                        if (!UserPermissionService.CheckPageCode(UserId, Pis.ApplicationId, Pis.PageCode, PsItem.Item_Value))
                        {
                            return false;
                        }
                        else
                        {
                            //检测页面文件url权限
                            PsItem = Get_UrlPermissionItem(Pis.ItemList, Utility.GetScriptNameUrl.ToLower(), Utility.GetScriptFileName.ToLower());
                            if (PsItem == null)
                                return true;
                            return UserPermissionService.CheckPageCode(UserId, Pis.ApplicationId, Pis.PageCode, PsItem.Item_Value);
                        }
                    }
                }
                else
                {
                    return false;
                }
            }
        }

        /// <summary>
        /// 获取当前面页Url所属的PermissionItem
        /// </summary>
        /// <param name="List">权限</param>
        /// <param name="CheckUrlString">需要检测的url</param>
        /// <param name="checkfilename">过滤检测文件名</param>
        /// <returns>权限值</returns>
        public static PermissionItemEntity Get_UrlPermissionItem(List<PermissionItemEntity> List, string CheckUrlString, string checkfilename)
        {
            PermissionItemEntity PI = null;
            foreach (PermissionItemEntity var in List)
            {
                if (!string.IsNullOrEmpty(var.Item_FileList))
                {
                    foreach (string var1 in var.Item_FileList.Split(','))
                    {
                        if (!string.IsNullOrEmpty(var1))
                        {
                            if (string.Compare(var1, checkfilename, true) != 0)
                            {
                                if (CheckUrlString.Contains(var1))
                                {
                                    return var;
                                }
                            }
                        }
                    }
                }
            }
            return PI;
        }

        /// <summary>
        /// 获取当前访问网页文件名格式: ,文件名,
        /// </summary>
        public static string Get_Script_Name
        {
            get
            {
                string Script_Name = Utility.GetScriptName;
                Script_Name = Script_Name.Substring(Script_Name.LastIndexOf("/") + 1);
                return string.Format(",{0},", Script_Name);
            }
        }

        /// <summary>
        /// 获取当前面页所属的PermissionItem
        /// </summary>
        /// <param name="List">权限列表</param>
        /// <returns></returns>
        public static PermissionItemEntity Get_PermissionItem(List<PermissionItemEntity> List)
        {
            PermissionItemEntity PI = null;
            foreach (PermissionItemEntity var in List)
            {
                if (var.Item_FileList.IndexOf(Get_Script_Name.ToLower()) >= 0)
                {
                    return var;
                }
            }
            return PI;
        }

        /// <summary>
        /// 获取当前目录下权限配置集合
        /// </summary>
        /// <returns></returns>
        public static PermissionEntity Get_Permission
        {
            get
            {
                return (PermissionEntity)ConfigurationManager.GetSection("PermissionEntity");
            }
        }

        /// <summary>
        /// 检测权限
        /// </summary>
        /// <param name="PType">权限类型 枚举类型</param>
        /// <returns></returns>
        public static bool CheckButtonPermission(Utility.PopedomType PType)
        {
            PermissionEntity premission = Get_Permission;
            if (premission == null)
            {
                return true;
            }
            //返回用户判断信息

            bool rBool = false;
            rBool = UserPermissionService.CheckPageCode(Utility.Get_UserId, premission.ApplicationId, premission.PageCode, (int)PType);
            return rBool;

        }

        /// <summary>
        /// 检测权限(出提示框)
        /// </summary>
        /// <param name="PType"></param>
        public static void CheckPermissionVoid(Utility.PopedomType PType)
        {
            if (!CheckButtonPermission(PType))
            {
                System.Web.HttpContext.Current.Response.Redirect("/Error.aspx");
                System.Web.HttpContext.Current.Response.End();
            }
        }


        /// <summary>
        /// 根据CMD检测权限
        /// </summary>
        /// <param name="CMD"></param>
        public static void CheckPagePermission(string CMD)
        {
            switch (CMD)
            {
                case "List":
                    CheckPermissionVoid(Utility.PopedomType.List);
                    break;
                case "New":
                    CheckPermissionVoid(Utility.PopedomType.New);
                    break;
                case "Edit":
                    CheckPermissionVoid(Utility.PopedomType.Edit);
                    break;
                case "OrderBy":
                    CheckPermissionVoid(Utility.PopedomType.Orderby);
                    break;
                case "Print":
                    CheckPermissionVoid(Utility.PopedomType.Print);
                    break;
                case "Delete":
                    CheckPermissionVoid(Utility.PopedomType.Delete);
                    break;
            }

        }

        /// <summary>
        /// 移除用户无权限模块列表
        /// </summary>
        /// <param name="list"></param>
        public static void RemoveNoPermission(List<ModuleEntity> list)
        {
            int iCount = list.Count;
            for (int i = 0; i <= iCount; i++)
            {
                int iIndex = 0;
                foreach (ModuleEntity var in list)
                {
                    bool rbool = UserPermissionService.CheckPageCode(Utility.Get_UserId, 1, var.MCODE);
                    if (!rbool)
                    {
                        list.RemoveAt(iIndex);
                        break;
                    }
                    iIndex++;
                }
            }
        }

        #region IHttpModule 成员

        void IHttpModule.Dispose()
        {

        }
        #endregion
    }
}
